package com.yycx.module.bus.provider.handler.haiying.tasktodo.settle.invoice;

import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.yycx.common.base.entity.EntityMap;
import com.yycx.common.base.utils.FlymeUtils;
import com.yycx.common.constants.CommonConstants;
import com.yycx.common.mybatis.interceptor.SaveInterceptor;
import com.yycx.common.mybatis.interceptor.UpdateInterceptor;
import com.yycx.common.mybatis.query.CriteriaSave;
import com.yycx.common.mybatis.query.CriteriaUpdate;
import com.yycx.common.security.OpenHelper;
import com.yycx.common.utils.ApiAssert;
import com.yycx.common.utils.RedisUtils;
import com.yycx.module.bus.client.entity.*;
import com.yycx.module.bus.client.entity.hy.BusHyorderInovice;
import com.yycx.module.bus.client.entity.hy.BusHyorderInoviceDetails;
import com.yycx.module.bus.client.enums.AmountTypeEnum;
import com.yycx.module.bus.provider.handler.haiying.BusinessUtils;
import com.yycx.module.bus.provider.service.*;
import com.yycx.module.bus.provider.service.hy.BusHyorderInoviceDetailsService;
import com.yycx.module.bus.provider.service.hy.BusHyorderInoviceService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.BitSet;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 开票保存扩展器
 *
 * @author zyf
 */
@Component
public class HyInvoicePaymentSaveHandler implements SaveInterceptor<BusPayment> {

    @Resource
    private BusPaymentService paymentService;

    @Resource
    private BusDeptService deptService;

    @Resource
    private BusSalemanService salemanService;

    @Resource
    private BusInvoiceunitService invoiceunitService;

    @Resource
    public RedisUtils redisUtils;


    @Autowired
    private BusinessUtils businessUtils;

    @Autowired
    private BusHyorderInoviceDetailsService orderInoviceDetailsService;
    @Autowired
    private BusHyorderInoviceService hyorderInoviceService;

    @Override
    public void prepare(CriteriaSave cs, EntityMap params, BusPayment payment) {
        //结算明细
        String selectIds = cs.getParams("selectIds");
        ApiAssert.isNotEmpty("结算明细不能为空", selectIds);
        //发票类型(2:专票 1:普票)
        Integer invoiceType = cs.getInt("invoiceType", 2);
        //是否包票1包 0不包
        Integer baopiao = cs.getInt("baopiao", 1);
        payment.setBaopiao(baopiao);
        payment.setInvoiceType(invoiceType);
        initPayments(payment, selectIds);
    }

    private void initPayments(BusPayment payment, String selectIds) {
        String[] selectIdsArrar = selectIds.split(",");
        BigDecimal totalSettleAmount = new BigDecimal("0");
        BigDecimal totalInvoiceAmount = new BigDecimal("0");
        BigDecimal totalTaxAmount = new BigDecimal("0");
        BigDecimal totalSecondTaxAmount = new BigDecimal("0");
        BigDecimal totalNoTaxAmount = new BigDecimal("0");
        BigDecimal totalSenondInvoiceAmount = new BigDecimal("0");
        BusHyorderInovice hyorderInovice = new BusHyorderInovice();
        hyorderInovice.setInoviceId(IdWorker.getId());
        hyorderInovice.setInvoiceUnitId(payment.getInvoiceUnitId());
        hyorderInovice.setCompanyId(OpenHelper.getCompanyId());
        hyorderInovice.setUserId(OpenHelper.getUserId());
        hyorderInovice.setBaopiao(payment.getBaopiao());
        hyorderInovice.setInvoiceType(payment.getInvoiceType());
        hyorderInovice.setTitle(payment.getTitle());
        //开票单位ID
        Long invoiceUnitId = payment.getInvoiceUnitId();
        BusInvoiceunit invoiceUnit = invoiceunitService.getById(invoiceUnitId);
        ApiAssert.isNotEmpty("开票单位不存在", invoiceUnit);
        for (String paymentId : selectIdsArrar) {
            BusPayment old = paymentService.getById(paymentId);
            old.setInvoiceUnitId(payment.getInvoiceUnitId());
            old.setBaopiao(payment.getBaopiao());
            old.setInvoiceType(payment.getInvoiceType());
            //系统配置
            EntityMap config = redisUtils.getConfigMap("DBR_CONFIG");
            //税率
            BigDecimal tax = FlymeUtils.getBigDecimal(config.getBigDecimal("tax"), "1.03");

            Long companyId = old.getCompanyId();

            //结算类型
            Integer settleType = old.getSettleType();
            List<BusPayment> settlePaymentList = new ArrayList<>();
            //发票类型(2:专票 1:普票)
            Integer invoiceType = old.getInvoiceType();
            //是否包票1包 0不包
            Integer baopiao = old.getBaopiao();
            //开票申请ID
            Long invoicePaymentId = old.getPaymentId();
            //合计结算金额
            BigDecimal settleAmount = old.getAmount();
            totalSettleAmount = totalSettleAmount.add(settleAmount);
            BusSaleman saleman = salemanService.getById(old.getSaleManId());
            //收款方(取开票单位)
            old.setPayeeName(saleman.getSaleManName());
            old.setSaleManCode(saleman.getSaleManBusinessNo());

            BigDecimal taxRate = new BigDecimal(invoiceUnit.getTaxNo());
            //开票金额
            BigDecimal invoiceAmount = new BigDecimal("0");
            //二次开票金额
            BigDecimal senondInvoiceAmount = new BigDecimal("0");
            //二次税金
            BigDecimal secondTaxAmount = new BigDecimal("0");
            //查询部门
            BusDept dept = deptService.getById(old.getDeptId());
            ApiAssert.isNotEmpty("部门不存在", dept);
            BigDecimal invoiceRate = FlymeUtils.getBigDecimal(dept.getInvoiceRate(), "1.0423");
            //包票
            if (baopiao.equals(1)) {
                //开票金额(个位取整) 开票金额=市场结算金额 * 1.0423或者1.0549
                invoiceAmount = getRoundAmount(settleAmount.multiply(invoiceRate));
                //二次开票金额 预提税金=开票金额/1.03*0.03*1.0423  （按部门配置结算标准）
                senondInvoiceAmount = getRoundAmount(invoiceAmount.divide(tax, 2, BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal("0.03")).multiply(invoiceRate));
                //二次税金 二次开票金额/1.03*0.0418   江苏二部是0.0536
                secondTaxAmount = senondInvoiceAmount.divide(tax, 2, BigDecimal.ROUND_HALF_UP).multiply(taxRate).setScale(2, BigDecimal.ROUND_HALF_UP);

            } else {
                //专票
                if (invoiceType.equals(2)) {
                    //开票金额(专票)=市场结算金额*1.03 或者1.06
                    invoiceAmount = getRoundAmount(settleAmount.multiply(tax));
                }
                //普票
                if (invoiceType.equals(1)) {
                    //开票金额(普票)=市场结算金额
                    invoiceAmount = settleAmount;
                }
            }
            totalInvoiceAmount = totalInvoiceAmount.add(invoiceAmount);
            //不含税金额
            BigDecimal noTaxAmount = invoiceAmount.divide(tax, 2, BigDecimal.ROUND_HALF_UP).setScale(2, BigDecimal.ROUND_HALF_UP);
            //税金金额
            BigDecimal taxAmount = invoiceAmount.divide(tax, 2, BigDecimal.ROUND_HALF_UP).multiply(taxRate).setScale(2, BigDecimal.ROUND_HALF_UP);
            totalTaxAmount = totalTaxAmount.add(taxAmount);
            totalSecondTaxAmount = totalSecondTaxAmount.add(secondTaxAmount);
            totalNoTaxAmount = totalNoTaxAmount.add(noTaxAmount);
            totalSenondInvoiceAmount = totalSenondInvoiceAmount.add(senondInvoiceAmount);
            old.setInvoiceType(invoiceType);
            old.setInvoiceAmount(invoiceAmount);
            old.setTaxAmount(taxAmount);
            old.setNoTaxAmount(noTaxAmount);
            old.setInvoiceUnitId(invoiceUnitId);
            old.setSecondTaxAmount(secondTaxAmount);
            old.setBaopiao(baopiao);
            old.setBankNo(invoiceUnit.getBankNo());
            old.setBankName(invoiceUnit.getBankName());
            old.setSenondInvoiceAmount(senondInvoiceAmount);
            old.setInvoiceId(hyorderInovice.getInoviceId());
            paymentService.updateById(old);
        }
        hyorderInovice.setInvoiceUnitId(invoiceUnitId);
        hyorderInovice.setInvoiceUnitName(invoiceUnit.getInvoiceunitName());
        hyorderInovice.setInvoiceBankNo(invoiceUnit.getBankNo());
        hyorderInovice.setInvoiceBankName(invoiceUnit.getBankName());
        hyorderInovice.setAmount(totalSettleAmount);
        hyorderInovice.setInvoiceAmount(totalInvoiceAmount);
        hyorderInovice.setNoTaxAmount(totalNoTaxAmount);
        hyorderInovice.setSecondTaxAmount(totalSecondTaxAmount);
        hyorderInovice.setSenondInvoiceAmount(totalSenondInvoiceAmount);
        hyorderInovice.setTaxAmount(totalTaxAmount);
        hyorderInoviceService.save(hyorderInovice);
        orderInoviceDetailsService.updateSettleInvoiceId(hyorderInovice,selectIdsArrar);
    }

    /**
     * 个位四舍五入
     *
     * @param invoiceAmount
     * @return
     */
    private BigDecimal getRoundAmount(BigDecimal invoiceAmount) {
        return invoiceAmount.divide(new BigDecimal(10)).setScale(0, BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal("10"));
    }
}
